﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Interop;

namespace WpfFlipit
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        #region Win32 API functions

        [DllImport("user32.dll")]
        static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        [DllImport("user32.dll")]
        static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

        [DllImport("user32.dll", SetLastError = true)]
        static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        [DllImport("user32.dll")]
        static extern bool GetClientRect(IntPtr hWnd, out Rectangle lpRect);

        #endregion

        #region 字段
        private readonly FlipItSettings _settings;
        private bool _isPreviewMode = false;
        private Point _mouseLocation;
        #endregion

        #region 构造函数
        public MainWindow(FlipItSettings settings)
        {
            InitializeComponent();
            this.RegisterEvent();
            this._settings = settings;
        }

        public MainWindow(FlipItSettings settings, double width, double height) : this(settings)
        {
            this.Width = width;
            this.Height = height;
            this.Left = this.Top = 0;
        }

        public MainWindow(FlipItSettings settings, IntPtr previewWndHandle) : this(settings)
        {
            IntPtr hwnd = new WindowInteropHelper(this).Handle;

            // Set the preview window as the parent of this window
            SetParent(hwnd, previewWndHandle);

            // Make this a child window so it will close when the parent dialog closes
            SetWindowLong(hwnd, -16, new IntPtr(GetWindowLong(hwnd, -16) | 0x40000000));

            // Place our window inside the parent
            GetClientRect(previewWndHandle, out var parentRect);

            this.Width = parentRect.Width;
            this.Height = parentRect.Height;
            this.Left = this.Top = 0;

            _isPreviewMode = true;
        }
        #endregion

        #region private方法
        /// <summary>
        /// 注册事件
        /// </summary>
        private void RegisterEvent()
        {
            this.Loaded += this.MainWindow_Loaded;
            this.KeyDown += this.MainWindow_KeyDown;
            this.MouseDown += this.MainWindow_MouseDown;
            this.MouseMove += this.MainWindow_MouseMove;
        }

        private void Exit()
        {
            if (!this._isPreviewMode)
            {
                Application.Current.Shutdown();
            }
        }
        #endregion

        #region 事件处理
        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            this.Cursor = Cursors.None;
            this.Topmost = true;

            if (!string.IsNullOrEmpty(this._settings.FontFamily))
            {
                this.flipClock.FontFamily = new FontFamily(this._settings.FontFamily);
            }

            if (!string.IsNullOrEmpty(this._settings.FontSize))
            {
                this.flipClock.FontSize = double.Parse(this._settings.FontSize);
            }

            this.flipClock.ShowSeconds = this._settings.ShowSeconds;
            this.flipClock.Display24HrTime = this._settings.Display24HrTime;
        }

        private void MainWindow_MouseMove(object sender, MouseEventArgs e)
        {
            if (!this._isPreviewMode)
            {
                if (this._mouseLocation != new Point(0, 0))
                {
                    if (this._mouseLocation != e.GetPosition(this))
                        Application.Current.Shutdown();
                }

                // Update current mouse location
                _mouseLocation = e.GetPosition(this);
            }
        }

        private void MainWindow_MouseDown(object sender, MouseButtonEventArgs e)
        {
            this.Exit();
        }

        private void MainWindow_KeyDown(object sender, KeyEventArgs e)
        {
            this.Exit();
        }
        #endregion
    }
}
